﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;



namespace demo.Web.AzureTables
{
    public class DepartmentDataSource
    {
        private string _companyCode;
        private DepartmentContext _ctx = new DepartmentContext();
        private string _myTableName = DepartmentContext.TableName;


        public DepartmentDataSource(string companyCode)
        {
            this._companyCode = companyCode;
        }


        public IQueryable<Department> SelectAll()
        {
            string pKey = Department.MakePartitionKey(this._companyCode);
            var results = from g in this._ctx.Departments
                          where g.PartitionKey == pKey
                          select g;
            return results;
        }

        /// <summary>
        /// 1 row via row key.
        /// </summary>
        /// <returns></returns>
        public IQueryable<Department> SelectRow(string rowKey)
        {
            string pKey = Department.MakePartitionKey(this._companyCode);
            return SelectRow(pKey, rowKey);
        }

        /// <summary>
        /// 1 row via partition & row key.  Internal use only
        /// </summary>
        /// <returns></returns>
        private IQueryable<Department> SelectRow(string pKey, string rowKey)
        {
            var results = from g in this._ctx.Departments
                          where g.PartitionKey == pKey
                             && g.RowKey == rowKey
                          select g;
            return results;
        }


        /// <summary>
        /// loads a SINGLE record from an immmutable composite ID (i.e. what you would find embedded in
        /// other records as a foriegn key)
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public Department LoadFromCompositeID(string ID)
        {
            // assume not found
            Department myRecord = null;

            // break apart the composite key into partition & row components
            string[] keyParts = ATSEntityBase.ParseID(ID);
            string pKey = keyParts[0];
            string rKey = keyParts[1];

            // read the (row key) record for this key.
            // assume that row may no longer be on file
            var qry = SelectRow(pKey, rKey);
            try
            {
                foreach (Department dataRow in qry)
                {
                    myRecord = dataRow;
                    break;
                }
            }
            catch { }

            return myRecord;
        }




        /// <summary>
        /// handle both insert and update functions (i.e. add if new, update if already on file)
        /// </summary>
        /// <param name="myItem"></param>
        public void Upsert(Department myItem)
        {
            // copy properties to save them from being clobbered when we read for the original row
            Department deptClone = new Department();
            ATSEntityBase.CopyProperties(myItem, deptClone);


            // see if row is already on file.
            // if not, this is really an add
            Department origItem = null;
            if (myItem.PartitionKey != null && myItem.PartitionKey.Length > 0
                && myItem.RowKey != null && myItem.RowKey.Length > 0)
            {
                var qry = SelectRow(myItem.PartitionKey, myItem.RowKey);
                try
                {
                    // note: finding the record on file clobbers 'myItem'.
                    foreach (Department m in qry)
                    {
                        origItem = m;
                        break;
                    }
                }
                catch {  }         // error means record is new or no longer on file.  Treat as an 'add'
                
            }

            if (origItem == null)
            {
                Add(myItem);
            }
            else
            {
                Update(deptClone, origItem);
            }

            _ctx.SaveChanges();

        }


        private void Add(Department myItem)
        {

            DateTime ts = DateTime.Now;
            myItem.CreateDate = ts;
            myItem.UpdateDate = ts;

            this._ctx.AddObject(_myTableName, myItem);
        }


        private void Update(Department myItem, Department origItem)
        {

            myItem.UpdateDate = DateTime.Now;

            ATSEntityBase.CopyProperties(myItem, origItem);
            this._ctx.UpdateObject(origItem);
        }

    }
}